package com.gzy.rpsm.property.config;

import com.gzy.rpsm.property.pojo.ResponsePojo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.server.ResponseStatusException;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 控制器增强器则用于处理异常和响应封装
 * 统一封装异常返回
 */
@Slf4j
@ControllerAdvice
public class ExceptionAdvice {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponsePojo methodArgumentNotValid(MethodArgumentNotValidException ex,
                                               HttpServletRequest request) {
        log.error("request {} throw MethodArgumentNotValidException \n", request.getRequestURI(), ex);
        return ResponsePojo.fail( ex.toString(),"参数校验失败");
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public ResponsePojo methodArgumentTypeMismatch(MethodArgumentTypeMismatchException ex,
                                                   HttpServletRequest request) {
        log.error("request {} throw MethodArgumentTypeMismatchException \n", request.getRequestURI(), ex);
        return ResponsePojo.fail( ex.toString(),"参数类型不匹配");
    }

    /**
     * 拦截403错误
     *
     * @param ex 异常
     * @param request 请求参数
     * @return 接口响应
     */
    @ExceptionHandler(ResponseStatusException.class)
    @ResponseBody
    public ResponsePojo handleForbiddenException(ResponseStatusException ex, HttpServletRequest request) {
        if (ex.getStatus() == HttpStatus.FORBIDDEN) {
            log.error("request {} was forbidden \n", request.getRequestURI());
            return ResponsePojo.fail(null, "Authorization无信息，未登录");
        }
        // 如果不是403错误，则重新抛出异常以便其他异常处理器处理
        throw ex;
    }

    /**
     * 其他异常拦截
     * @param ex 异常
     * @param request 请求参数
     * @return 接口响应
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponsePojo handleException(Exception ex, HttpServletRequest request) {
        log.error("request {} throw unExpectException \n", request.getRequestURI(), ex);
        return ResponsePojo.fail(ex.toString(),"未知异常，请联系管理员");
    }
}